﻿namespace IBTrader.Indicator.Channel
{
    using IBTrader.Indicator.Average;
    using IBTrader.Modules.Read;
    using IBTrader.Charts;
    using System;
    using System.Linq;

    /// <summary>
    /// Developed by John Bollinger, Bollinger Bands are volatility bands placed above and below a moving average. 
    /// Volatility is based on the standard deviation, which changes a volatility increase and decreases. 
    /// The bands automatically widen when volatility increases and narrow when volatility decreases. 
    /// This dynamic nature of Bollinger Bands also means they can be used on different securities with the standard settings. 
    /// For signals, Bollinger Bands can be used to identify M-Tops and W-Bottoms or to determine the strength of the trend. 
    /// Signals derived from narrowing BandWidth are discussed in the chart school article on BandWidth.
    /// </summary>
    class BollingerBand : BaseUpDown
    {
        private readonly SMA [] sma;
        private double avg, dev;
        private readonly float factor;
        internal BollingerBand(Worker worker, int interval1 = 60, int interval2 = 60, float factor = 2f) : base(worker)
        {
            sma = new[] { interval1, interval2 }.Select(i => new SMA(worker, i)).ToArray();
            sma[0].Hit += (_, line) => avg = line.Price;
            sma[1].Hit += (_, line) => dev = Math.Sqrt(line.Price);
            this.factor = factor;
        }
        public override void Add(object sender, Line line)
        {
            sma[0].Add(sender, line);
            if (avg == 0) return;
            sma[1].Add(sender, NewLine(line, Math.Pow(line.Price - avg, 2)));
            OnUp(line, avg + factor * dev);
            OnDown(line, avg - factor * dev);
            OnHit(line, avg);
        }
    }
}